package com.kinghunt.misp.service.impl.userx;

import com.kinghunt.misp.common.param.userx.PermissionParam;
import com.kinghunt.misp.common.utils.PermissionConverter;
import com.kinghunt.misp.dal.dao.userx.*;
import com.kinghunt.misp.dal.model.userx.PermissionDO;
import com.kinghunt.misp.dal.model.userx.RolePermissionDO;
import com.kinghunt.misp.dal.model.userx.UserPermissionBlacklistDO;
import com.kinghunt.misp.dal.model.userx.UserPermissionDO;
import com.kinghunt.misp.service.api.userx.PermissionWriteService;
import com.bygoodtech.kings.base.utils.ConvertUtil;
import com.bygoodtech.kings.common.dto.ApiResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description 权限
 * @Author jiangtao
 * @Date 2023/7/5 22:14
 */
@Service
public class PermissionWriteServiceImpl implements PermissionWriteService {

    @Autowired(required = false)
    PermissionDAO permissionDAO;
    @Autowired(required = false)
    RolePermissionDAO rolePermissionDAO;
    @Autowired(required = false)
    UserRoleDAO userRoleDAO;
    @Autowired(required = false)
    UserPermissionDAO userPermissionDAO;
    @Autowired(required = false)
    UserPermissionBlacklistDAO userPermissionBlacklistDAO;

    @Override
    public ApiResult<Boolean> addSystemPermission(PermissionParam permissionParam) {
        PermissionDO record = ConvertUtil.convert(permissionParam, PermissionDO.class);
        record.setIsDel(Boolean.FALSE);
        int ret = permissionDAO.insert(record);
        return ApiResult.ok(true);
    }

    @Override
    public ApiResult<Boolean> updateRolePermission(Long roleId, List<Long> permissionIds) {
        rolePermissionDAO.deleteByRoleId(roleId);

        if (CollectionUtils.isEmpty(permissionIds)) {
            return ApiResult.ok(true);
        }
        List<PermissionDO> permissions = permissionDAO.selectByIds(permissionIds);
        List<RolePermissionDO> rolePermissionDOS = PermissionConverter.convert2RolePermissionDOs(roleId, permissions);
        if (! CollectionUtils.isEmpty(rolePermissionDOS)) {
            rolePermissionDAO.insertBatch(rolePermissionDOS);
        }
        return ApiResult.ok(true);
    }

    @Override
    public ApiResult<Boolean> updateUserPermission(Long userId, List<Long> permissionIds) {
        Set<Long> userRolePermissions = new HashSet<>();
        List<Long> userRoleIds = userRoleDAO.selectRoleIdsByUserId(userId);
        if (! CollectionUtils.isEmpty(userRoleIds)) {
            List<RolePermissionDO> rolePermissionDOS = rolePermissionDAO.selectByRoleIds(userRoleIds);
            userRolePermissions.addAll(rolePermissionDOS.stream().map(RolePermissionDO::getPermissionId).collect(Collectors.toSet()));
        }

        // 计算白名单
        Set<Long> whiteSet = new HashSet<>();
        whiteSet.addAll(permissionIds);
        whiteSet.removeAll(userRolePermissions);
        List<PermissionDO> whitePermissions = permissionDAO.selectByIds(new ArrayList<>(whiteSet));
        userPermissionDAO.deleteByUserId(userId);
        if (! CollectionUtils.isEmpty(whitePermissions)) {
            List<UserPermissionDO> records = PermissionConverter.convert2UserPermissionDOs(userId, whitePermissions);
            userPermissionDAO.insertBatch(records);
        }

        // 计算黑名单
        Set<Long> blackSet = new HashSet<>();
        blackSet.addAll(userRolePermissions);
        blackSet.removeAll(permissionIds);
        List<PermissionDO> blackPermissions = permissionDAO.selectByIds(new ArrayList<>(blackSet));
        userPermissionBlacklistDAO.deleteByUserId(userId);
        if (! CollectionUtils.isEmpty(blackPermissions)) {
            List<UserPermissionBlacklistDO> records = PermissionConverter.convert2UserPermissionBlacklistDOs(userId, blackPermissions);
            userPermissionBlacklistDAO.insertBatch(records);
        }

        return ApiResult.ok(Boolean.TRUE);
    }
}
